"""
德州扑克手牌解析模块。
提供手牌字符串解析、格式化和比较等功能。
"""
from typing import List, Tuple, Optional
from enum import Enum

class Suit(Enum):
    """花色枚举"""
    HEARTS = 'h'    # 红桃
    SPADES = 's'    # 黑桃
    DIAMONDS = 'd'  # 方块
    CLUBS = 'c'     # 梅花

class Card:
    """
    扑克牌类，表示一张扑克牌
    """
    # 点数映射表
    RANK_MAP = {
        'T': 10,
        'J': 11,
        'Q': 12,
        'K': 13,
        'A': 14
    }
    
    def __init__(self, card_str: str):
        """
        初始化一张扑克牌
        Args:
            card_str: 牌面字符串，如'As', 'Th', '8d'等
        """
        if len(card_str) != 2:
            raise ValueError(f"Invalid card string: {card_str}")
            
        rank_char = card_str[0].upper()
        suit_char = card_str[1].lower()
        
        # 解析点数
        if rank_char in self.RANK_MAP:
            self.rank = self.RANK_MAP[rank_char]
        elif rank_char.isdigit() and 2 <= int(rank_char) <= 9:
            self.rank = int(rank_char)
        else:
            raise ValueError(f"Invalid rank: {rank_char}")
            
        # 解析花色
        try:
            self.suit = Suit(suit_char)
        except ValueError:
            raise ValueError(f"Invalid suit: {suit_char}")
            
    def __str__(self) -> str:
        """返回牌面的字符串表示"""
        # 反向查找点数映射
        rank_str = next(
            (k for k, v in self.RANK_MAP.items() if v == self.rank),
            str(self.rank)
        )
        return f"{rank_str}{self.suit.value}"
        
    def __eq__(self, other) -> bool:
        """比较两张牌是否相等"""
        if not isinstance(other, Card):
            return False
        return self.rank == other.rank and self.suit == other.suit

class Hand:
    """
    手牌类，表示一个德州扑克手牌
    """
    def __init__(self, hand_str: str):
        """
        初始化手牌
        Args:
            hand_str: 手牌字符串，如'AhKs', '8h7h', 'TdTc'等
        """
        if len(hand_str) != 4:
            raise ValueError(f"Invalid hand string: {hand_str}")
            
        # 解析两张牌
        self.card1 = Card(hand_str[:2])
        self.card2 = Card(hand_str[2:])
        
        # 确保点数大的牌在前
        if self.card1.rank < self.card2.rank:
            self.card1, self.card2 = self.card2, self.card1
            
    def is_pocket_pair(self) -> bool:
        """判断是否为口袋对"""
        return self.card1.rank == self.card2.rank
        
    def is_suited(self) -> bool:
        """判断是否为同花"""
        return self.card1.suit == self.card2.suit
        
    def to_range_notation(self) -> str:
        """
        转换为范围表标准记号
        Returns:
            str: 范围表标准记号，如'AKs', 'AKo', 'TT'等
        """
        # 获取点数的字符表示
        rank1 = next(
            (k for k, v in Card.RANK_MAP.items() if v == self.card1.rank),
            str(self.card1.rank)
        )
        rank2 = next(
            (k for k, v in Card.RANK_MAP.items() if v == self.card2.rank),
            str(self.card2.rank)
        )
        
        # 如果是口袋对
        if self.is_pocket_pair():
            return f"{rank1}{rank1}"
            
        # 如果是同花或不同花
        suffix = 's' if self.is_suited() else 'o'
        return f"{rank1}{rank2}{suffix}"
        
    def __str__(self) -> str:
        """返回手牌的字符串表示"""
        return f"{self.card1}{self.card2}" 